﻿#define _CRT_SECURE_NO_WARNINGS
#include"smartptr.h"
double Divide(int a, int b)
{
	// 当b == 0时抛出异常
	if (b == 0)
	{
		throw "Divide by zero condition!";
	}
	else
	{
		return (double)a / (double)b;
	}
}
void Func()
{
	// 这⾥可以看到如果发⽣除0错误抛出异常，另外下⾯的array和array2没有得到释放。
	// 所以这⾥捕获异常后并不处理异常，异常还是交给外⾯处理，这⾥捕获了再重新抛出去。
	// 但是如果array2new的时候抛异常呢，就还需要套⼀层捕获释放逻辑，这⾥更好解决⽅案
	// 是智能指针。
	int* array1 = new int[10];
	int* array2 = new int[10]; // 抛异常呢
	try
	{
		int len, time;
		cin >> len >> time;
		cout << Divide(len, time) << endl;
	}
	catch (...)
	{
		cout << "delete []" << array1 << endl;
		cout << "delete []" << array2 << endl;
		delete[] array1;
		delete[] array2;
		throw; // 异常重新抛出，捕获到什么抛出什么
	}
	// ...
	cout << "delete []" << array1 << endl;
	delete[] array1;
	cout << "delete []" << array2 << endl;
	delete[] array2;
}
void test1()
{
	try
	{
		Func();
	}
	catch (const char* errmsg)
	{
		cout << errmsg << endl;
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}
	catch (...)
	{
		cout << "未知异常" << endl;
	}
}


//简单的智能指针实现：
template<class T>
struct SmartPtr {
	SmartPtr(T* ptr) :_ptr(ptr) {

	}
	SmartPtr(const SmartPtr&s) :_ptr(s._ptr) {

	}
	T& operator*() {
		return *_ptr;
	}
	T* operator->() {
		return _ptr;
	}
	T& operator[](size_t pos) {
		return *(_ptr + pos);
	}

	~SmartPtr() {
		cout << "delete[] ..." << endl;
		delete[] _ptr;
	}
	T* _ptr = nullptr;
};
void test() {

	SmartPtr<int> sp1 = new int[10];
	SmartPtr<int> sp2 = sp1;
	
}

void test_auto_ptr() {

	auto_ptr<int> ap1(new int(10));

	auto_ptr<int> ap2(ap1);

	cout << *ap2 << endl;
	cout << *ap1 << endl;
}

//struct Person {
//	int _age;
//	string _name;
//};
//void test_unique_ptr() {
//	unique_ptr<Person> up1(new Person({ 18,"lwx" }));
//
//	//报错：不支持拷贝
//	//unique_ptr<Person> up2(up1); 
//
//	//只支持移动
//	unique_ptr<Person> up2(move(up1));  //move(左值)==右值 
//
//}

struct Person {
	Person(const int& age, const string& name) :_age(age), _name(name) {

	}
	int _age;
	string _name;
};
void test_shared_ptr() {
	shared_ptr<Person> sp1(new Person({ 20,"hlp" }));
	shared_ptr<Person> sp2(sp1);
	cout << sp1->_age << "  " << sp1->_name << endl;
	cout << sp2->_age << "  " << sp2->_name << endl;

	//也支持移动，sp1会被置空
	shared_ptr<Person> sp3(move(sp1));
	cout << sp3->_age << "  " << sp3->_name << endl;

}

//shared_ptr的多种构造方式
void test2() {

	shared_ptr<Person> sp1(new Person({ 19,"lwx" }));

	shared_ptr<Person> sp2 = make_shared<Person>(29,"hlp");

	auto sp3 = make_shared<Person>(39, "lpo");

	shared_ptr<Person> sp4;


	//不可以，报错！！！
	//shared_ptr<Person> sp5 = new Person({ 29,"cda" }); 
}

//shared_ptr和unique_ptr都支持bool类型转换
void test3() {
	shared_ptr<int> sp1(new int(10));
	shared_ptr<int> sp2;

	if (sp1) {
		cout << "sp1不为空" << endl;
	}
	if (!sp2) {
		cout << "sp2为空,不管理资源" << endl;
	}

}


//测试自己实现的shared_ptr
void test4() {
	Shared_ptr::shared_ptr<int> sp1;
	Shared_ptr::shared_ptr<int> sp2(new int(10));
	Shared_ptr::shared_ptr<int> sp3(sp2);
	//sp1 = sp2;

	cout << *sp1 << endl;
	cout << *sp2 << endl;
	cout << *sp3 << endl;
	
}
int main() {
	test4();
	return 0;
}
